import time
from comm import Config

from data.model.Params import *
from data.model.Trade import *

from broker.tws.RestApi import RestApi

class Exchange(object):

    def __init__(self, accountId: str, port: int = Config.FUTU_OPEND_PORT):
        self.port = port
        self.accountId = accountId  # 交易所账户
        self.restApi = RestApi(self.port)

    def tickle(self) -> (RET, Tickle):
        return self.restApi.tickle()

    def GetAccountSummary(self) -> (RET, AccountSummary):
        """
        returns an object containing account summary. The object contains multiple properties.
        A property is sufficed with -c if its provides commodity value, -s if it provides security value and -c if its UKL segment value
        """
        return self.restApi.accountSummary(self.accountId)

    def GetAccountLedger(self) -> (RET, AccountLedger):
        """
        returns an object containing account summary. The object contains multiple properties.
        A property is sufficed with -c if its provides commodity value, -s if it provides security value and -c if its UKL segment value
        """
        return self.restApi.accountLedger(self.accountId)

    def PreviewOrders(self, order: OrderReq) -> (RET, PreOrder):
        """
        preview order without actually submitting the order and you can get commission information
        """
        ret, cont = self.restApi.secdef_search(order.ticker)
        if ret.code == RetCode.OK:
            order.acctId = self.accountId
            order.conid = cont.conid
        else:
            return ret, None
        return self.restApi.preview_orders(self.accountId, order)

    def GetTrades(self) -> (RET, list):
        return self.restApi.trades()



    def PlaceOrders(self, order: OrderReq) -> (RET, POrder):
        ret, cont = self.restApi.secdef_search(order.ticker)
        if ret.code == RetCode.OK:
            order.acctId = self.accountId
            order.conid = cont.conid
        else:
            return ret, None

        ret, porder = self.restApi.place_orders(self.accountId, order)
        if ret.code != RetCode.OK:
            return ret, porder

        ret, replyData = self.restApi.reply_order(porder.pid)
        if ret.code == RetCode.OK:
            porder.parse_reply(replyData)
        return ret, porder






    # def Open(self, direction, price, amount):
    #     """
    #     用于开新仓单，该函数返回一个订单ID。
    #     参数值：
    #     direction 为多空方向
    #     price 为订单价格，数值类型
    #     amount 为订单数量，数值类型
    #     """
    #     orderType = None
    #     if direction == Direction.BUY and price > PriceType.LIMIT:
    #         orderType = OrderType.BUY_LIMIT
    #     elif direction == Direction.BUY and price == PriceType.MARKET:
    #         orderType = OrderType.BUY_MARKET
    #     elif direction == Direction.SELL and price > PriceType.LIMIT:
    #         orderType = OrderType.SELL_LIMIT
    #     elif direction == Direction.SELL and price == PriceType.MARKET:
    #         orderType = OrderType.SELL_MARKET
    #
    #     tradeParam = CaddParam(self.symbol, TradeType.OPEN, orderType, amount)
    #     tradeParam.open(price, self.marginLevel)
    #     return contract.add(tradeParam)
    #
    # def Close(self, direction, price, amount):
    #     """
    #     用于平持仓单，该函数返回一个订单ID。
    #     参数值：
    #     direction 为多空方向
    #     price 为订单价格，数值类型
    #     amount 为订单数量，数值类型。
    #     """
    #     orderType = None
    #     if direction == Direction.BUY and price > PriceType.LIMIT:
    #         orderType = OrderType.BUY_LIMIT
    #     elif direction == Direction.BUY and price == PriceType.MARKET:
    #         orderType = OrderType.BUY_MARKET
    #     elif direction == Direction.SELL and price > PriceType.LIMIT:
    #         orderType = OrderType.SELL_LIMIT
    #     elif direction == Direction.SELL and price == PriceType.MARKET:
    #         orderType = OrderType.SELL_MARKET
    #
    #     tradeParam = CaddParam(self.symbol, TradeType.CLOSE, orderType, amount)
    #     tradeParam.close(price)
    #     return contract.add(tradeParam)
    #
    #
    #
    # def GetPosition(self):
    #     """
    #     获取当前持仓信息。返回值：position结构体数组。没有持仓则返回空数组，即[]
    #     """
    #     result = contract.position(self.symbol, MarginType.CROSS)
    #     positions = Position.parse(result)
    #     return positions
    #
    # def GetOrders(self):
    #     """
    #     获取所有未完成的订单。返回值：Order结构体数组。
    #     """
    #     result = contract.currentList(symbol=self.symbol)
    #     orders = Order.parse(result)
    #     return orders
    #
    # def CancelOrder(self):
    #     """
    #     取消货币对所有未完成的订单
    #     """
    #     contract.cancel(symbol=self.symbol)

